-- local function has_words_before()
--   local line, col = unpack(vim.api.nvim_win_get_cursor(0))
--   return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match "%s" == nil
-- end
local source_names = {
  nvim_lsp = "(LSP)",
  emoji = "(Emoji)",
  path = "(Path)",
  calc = "(Calc)",
  cmp_tabnine = "(Tabnine)",
  vsnip = "(Snippet)",
  luasnip = "(Snippet)",
  buffer = "(Buffer)",
  -- nvim_lsp_signature_help = "(Signature)",
  tmux = "(TMUX)",
  copilot = "(Copilot)",
  treesitter = "(TreeSitter)",
  vim_dadbod_completion = "(DADBOD)",
}

return {
  "hrsh7th/nvim-cmp",
  dependencies = {
    -- "AstroNvim/astrolsp",
    -- "hrsh7th/cmp-calc",
    -- "hrsh7th/cmp-emoji",
    {
      "hrsh7th/cmp-cmdline",
      keys = { ":", "/", "?" }, -- lazy load cmp on more keys along with insert mode
      dependencies = { "hrsh7th/nvim-cmp" },
      opts = function()
        local cmp = require "cmp"
        return {
          {
            -- completion = {
            --   completeopt = "menu,menuone,noselect",
            -- },
            type = "/",
            mapping = cmp.mapping.preset.cmdline(),
            sources = {
              { name = "buffer" },
            },
          },
          {
            -- completion = {
            --   completeopt = "menu,menuone,noselect",
            -- },
            type = ":",
            mapping = cmp.mapping.preset.cmdline(),
            sources = cmp.config.sources {
              { name = "path" },
              {
                name = "cmdline",
                option = {
                  ignore_cmds = { "Man", "!" },
                },
              },
            },
          },
        }
      end,
      config = function(_, opts)
        local cmp = require "cmp"
        vim.tbl_map(function(val) cmp.setup.cmdline(val.type, val) end, opts)
      end,
    },
    -- "hrsh7th/cmp-nvim-lsp-signature-help",
    -- "jc-doyle/cmp-pandoc-references",
    -- "kdheepak/cmp-latex-symbols",
  },
  opts = function(_, opts)
    local cmp = require "cmp"
    local lspkind = require "lspkind"

    return require("astronvim.utils").extend_tbl(opts, {
      experimental = { ghost_text = true },
      completion = {
        -- 自动选中第一条
        completeopt = "menu,menuone,noinsert",
      },
      sources = cmp.config.sources {
        { name = "nvim_lsp", priority = 1000 },
        { name = "luasnip", priority = 900 },
        { name = "path", priority = 750 },
        { name = "pandoc_references", priority = 725 },
        { name = "latex_symbols", priority = 700 },
        { name = "emoji", priority = 700 },
        { name = "calc", priority = 650 },
        { name = "buffer", priority = 250 },
        -- { name = 'nvim_lsp_signature_help', priority = 250 },
      },
      -- mapping = {
      -- ["<CR>"] = cmp.config.disable,
      -- ctrl + e关闭补全窗口
      -- ["<C-p>"] = cmp.mapping.select_prev_item { behavior = cmp.SelectBehavior.Select },
      -- ["<C-n>"] = cmp.mapping.select_next_item { behavior = cmp.SelectBehavior.Select },
      -- ["<C-k>"] = cmp.mapping.select_prev_item { behavior = cmp.SelectBehavior.Select },
      -- ["<C-j>"] = cmp.mapping.select_next_item { behavior = cmp.SelectBehavior.Select },
      --   ["<Tab>"] = cmp.mapping(function(fallback)
      --     -- idea输入方式
      --     if cmp.visible() then
      --       local entry = cmp.get_selected_entry()
      --       if not entry then
      --         cmp.select_next_item { behavior = cmp.SelectBehavior.Select }
      --       else
      --         if has_words_before() then
      --           cmp.confirm {
      --             behavior = cmp.ConfirmBehavior.Replace,
      --             select = false,
      --           }
      --         else
      --           cmp.confirm {
      --             behavior = cmp.ConfirmBehavior.Insert,
      --             select = false,
      --           }
      --         end
      --       end
      --     else
      --       fallback()
      --     end
      --   end, { "i", "s" }),
      --   ["<S-Tab>"] = cmp.config.disable,
      -- },

      formatting = {
        format = lspkind.cmp_format {
          with_text = true, -- do not show text alongside icons
          -- mode = "symbol",
          -- maxwidth = 50, -- prevent the popup from showing more than provided characters (e.g 50 will not show more than 50 characters)
          -- symbol_map = {
          --   Array = " ",
          --   Boolean = " ",
          --   Class = " ",
          --   Color = " ",
          --   Constant = " ",
          --   Constructor = " ",
          --   Enum = " ",
          --   EnumMember = " ",
          --   Event = " ",
          --   Field = " ",
          --   File = " ",
          --   Folder = " ",
          --   Function = " ",
          --   Interface = " ",
          --   Key = " ",
          --   Keyword = " ",
          --   Method = " ",
          --   Module = " ",
          --   Namespace = " ",
          --   Null = " ",
          --   Number = " ",
          --   Object = " ",
          --   Operator = " ",
          --   Package = " ",
          --   Property = " ",
          --   Reference = "  ",
          --   Snippet = " ",
          --   String = " ",
          --   Struct = " ",
          --   Text = " ",
          --   TypeParameter = " ",
          --   Unit = " ",
          --   Value = " ",
          --   Variable = " ",
          -- },
          before = function(entry, vim_item)
            -- Source 显示提示来源
            -- vim_item.menu = "[" .. string.upper(entry.source.name) .. "]"
            vim_item.menu = source_names[entry.source.name]
            return vim_item
          end,
        },
      },
    })
  end,
}
